import { UserType } from "@/store/store-util";
import { Broadcaster, DataChange } from "../broadcaster/Broadcaster";
import { getUserInfo } from '@/Util'
import axios from "axios";
import { CardType, DoubleMsgType, GameStatus, OutCardInfo, PlayerOutCardInfo, PlayerType, SummaryObjType } from "@/share/commonType";

export default class Hlddz extends Broadcaster { //前端和后端数据结构最好一致
    static instance: Hlddz | null;
    gameStatus: GameStatus; // 游戏进程
    userinfo: UserType = getUserInfo()
    myname: string = this.userinfo.username
    players: PlayerType[] = [];
    card: CardType[] = [];// 纸牌信息
    cardNum = {};// 纸牌数量
    landlord: string; // 地主
    landlordCard: CardType[] = [] // 地主牌
    gameId: string;
    lastOutCardInfo: PlayerOutCardInfo;
    compareCardInfo: OutCardInfo = null; // 要比较的牌
    nowOutCardPlayer: string;
    outCardList: { [key: string]: OutCardInfo };
    lowScore: number = 15; // 底分
    multiple: number = 15; // 倍数 ，欢乐豆结算等于底分乘倍数
    isCompleteDouble: boolean = false;
    completeDoublePlayer: string[] = [];
    constructor(model: Hlddz) {
        super()
        this.initModel(model)
    }

    initModel(model: Hlddz) {
        console.log(model)
        this.gameStatus = model.gameStatus
        this.players = model.players
        this.card = model.card
        this.cardNum = model.cardNum
        this.landlord = model.landlord
        this.landlordCard = model.landlordCard
        this.lastOutCardInfo = model.lastOutCardInfo
        this.nowOutCardPlayer = model.nowOutCardPlayer
        this.compareCardInfo = model.compareCardInfo
        this.outCardList = model.outCardList
        this.multiple = model.multiple
        this.isCompleteDouble = model.isCompleteDouble,
            this.completeDoublePlayer = model.completeDoublePlayer,
            this.gameId = model.gameId
    }

    async finishLoad() {
        let event = {
            action: DataChange.FinishLoad,
            data: {
                gameStatus: this.gameStatus
            }
        }
        this.broadcaster(event)
    }
    changeMultiple(msg: DoubleMsgType) {
        let { multiple, isCompleteDouble, completeDoublePlayer } = msg
        this.multiple = multiple
        this.isCompleteDouble = isCompleteDouble
        this.completeDoublePlayer = completeDoublePlayer
        let event = {
            action: DataChange.Double,
            data: msg
        }
        this.broadcaster(event)
    }

    clientOutCard(outCards: CardType[]) {// 本地客户端更新逻辑
        if (!outCards) return;
        outCards.forEach(({ cardNum, cardIcon }) => {
            let index = this.card.findIndex((item) => item.cardIcon === cardIcon && item.cardNum === cardNum)
            if (index !== -1) this.card.splice(index, 1);
        })
    }

    isIncluedPlayer(name: string): boolean {//判断用户是否在该游戏内
        return this.players.some(i => i?.name === name)
    }

    setLastOutCardInfo(msg: any) {
        const playerName = msg.outCardPlayer
        this.lastOutCardInfo = {
            playerName,
            outCardInfo: msg.outCardInfo
        }
        this.compareCardInfo = msg.nextPlayerCompareCardInfo
        this.nowOutCardPlayer = msg.nextOutCardPlayer
        this.cardNum = msg.cardNum
        let event = {
            action: DataChange.OutCard,
            data: {
                cardNum: this.cardNum[playerName],
                notBroad: this.myname === playerName || !msg.outCardInfo
            }
        }
        this.broadcaster(event)
    }

    outCard(lastOutCardInfo: PlayerOutCardInfo) { // iofunc调用
        this.lastOutCardInfo = lastOutCardInfo
        let newNum = this.cardNum[this.userinfo.username] - lastOutCardInfo.outCardInfo.rawCards.length
        this.cardNum[this.userinfo.username] = newNum;
        let event = {
            action: DataChange.MySelfOutCard,
            data: {
                cardNum: this.cardNum[this.myname],
                notBroad: !lastOutCardInfo.outCardInfo
            }
        }
        this.broadcaster(event)
    }

    changePlayer(newPlayers: PlayerType[], gameId?: string) { // iofunc调用
        if (gameId) this.gameId = gameId;
        this.players = newPlayers
        let event = {
            action: DataChange.PlayerChange,
            data: {}
        }
        this.broadcaster(event)
        if (this.players.every(i => i && i.status)) { // 每一个都不为空， 可以获取model开始游戏
            this.isNeedStart()
        }
    }

    getBeforeAndAfterPlayer(playerName?: string) {
        let beforePlayer: string
        let afterPlayer: string
        if (!this.players) return;
        let myName = playerName || this.userinfo.username;
        let index = this.players.findIndex((item) => item?.name === myName)
        let beforeIndex = index - 1 < 0 ? 2 : index - 1
        let afterIndex = index + 1 > 2 ? 0 : index + 1
        beforePlayer = this.players[beforeIndex]?.name
        afterPlayer = this.players[afterIndex]?.name
        return { beforePlayer, afterPlayer }
    }

    getPlayerInfo(name: string): PlayerType {
        if (!name) return
        return this.players.find((item) => item?.name === name)
    }

    async isNeedStart() {
        // 获取model的发牌信息
        let { data } = await axios.get('/game/model', {
            params: {
                gameid: this.gameId,
                playerName: this.userinfo.username
            }
        })
        let newModel: Hlddz = data.data
        this.initModel(newModel)
        this.gameStatus = GameStatus.Gaming
        let event = {
            action: DataChange.GameStart,
            data: {}
        }
        this.broadcaster(event)
    }
    async gameReStart() {
        let { data } = await axios.get('/game/model', {
            params: {
                gameid: this.gameId,
                playerName: this.userinfo.username
            }
        })
        let newModel: Hlddz = data.data
        this.initModel(newModel)
        this.broadcaster({
            action: DataChange.Restart,
            data: {}
        })
    }

    gameOver(summaryObj: SummaryObjType) {
        let event = {
            action: DataChange.GameOver,
            data: summaryObj
        }
        this.broadcaster(event)
    }

    static getInstance(model?: Hlddz) {
        if (!this.instance && model) {
            this.instance = new Hlddz(model)
        }
        return this.instance
    }

    static destroyInstance() {
        this.instance = null
    }
}